<template>
  <div>
    <button @click="insertTable(3, 3)">插入表格</button>
    <button @click="addColumn">添加列</button>
    <button @click="addRow">添加行</button>
    <button @click="deleteTable">删除表格</button>
    <button @click="mergeCells">合并单元格</button>
    <button @click="splitCell">拆分单元格</button>
    <button @click="deleteRow" :disabled="!canDeleteRow">删除行</button>
    <button @click="deleteColumn" :disabled="!canDeleteColumn">删除列</button>
    <br />
    <button @click="insertWord">插入一段话</button>
    <button @click="undo">撤销</button>
    <input v-model="replacementText" placeholder="输入替换内容" />
    <button @click="checkWordAndChange">取得选中的内容并替换</button>
    <button @click="findWordAndChange">模拟右侧抽屉替换</button>
    <input type="file" accept=".docx" @change="handleFileUpload" />
    <br />
    <!-- <button @click="insertMarkDown">模拟markdown数据</button>
    <button @click="exportMarkDown">导出markdown数据</button> -->
    <button @click="setAlignment('left')">靠左</button>
    <button @click="setAlignment('center')">居中</button>
    <button @click="setAlignment('right')">靠右</button>
    <button @click="turnBold">加粗</button>
    <button @click="toggleUnderline">下划线</button>

    字体大小
    <select name="fruits" v-model="fontsize" @change="setFontSize">
      <option value="12">12px</option>
      <option value="14">14px</option>
      <option value="16">16px</option>
      <option value="18">18px</option>
      <option value="20">20px</option>
    </select>
    <br />
    <div class="mainContent">
      <div class="toc-sidebar">
        <div
          v-for="item in tocItems"
          :key="item.id"
          :style="{ paddingLeft: (item.level - 2) * 20 + 'px' }"
          class="toc-item"
          @click="scrollToHeading(item.id)"
        >
          {{ item.text }}
        </div>
      </div>
      <div ref="editorElement" class="editorElement">
        <!-- 浮动菜单 -->
        <div v-show="toggleMenuFlag" class="menu-wrap">
          <button @click="editor.chain().focus().toggleBold().run()">
            加粗
          </button>
          <button @click="toggleUnderline">下划线</button>
          <button @click="startAI">AI智能</button>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
import { Editor } from "@tiptap/vue-2";
import StarterKit from "@tiptap/starter-kit";
// import { Collaboration } from "@tiptap/extension-collaboration";
// import { CollaborationCursor } from "@tiptap/extension-collaboration-cursor";
// import * as Y from "yjs";
// import { WebsocketProvider } from "y-websocket";
import TableRow from "@tiptap/extension-table-row";
import TableHeader from "@tiptap/extension-table-header";
// import mammoth from "mammoth/mammoth.browser";
import draggableImage from "./js/draggable-image";
import { CellSelection } from "prosemirror-tables";
import { markdownData } from "./js/markdown.js";
import { Node } from "@tiptap/core";
import Underline from "@tiptap/extension-underline";
import Color from "@tiptap/extension-color";
import Highlight from "@tiptap/extension-highlight";
import JSZip from "jszip";
import { DOMParser } from "xmldom";
// import { TextSelection } from "prosemirror-state";
import {
  TableCellMerge,
  HeadingWithId,
  CustomImage,
  // CustomTable,
  textAlign,
  tableCell,
  markDown,
  AlignableTable,
  textStyle,
  CustomParagraph,
  FontSize,
} from "./js/tipTapConfig.js";
export default {
  directives: { draggableImage },
  data() {
    return {
      menuPosition: 0,
      scrollTop: 0,
      menu: document.querySelector(".menu-wrap"),
      scrollParents: [],
      rafId: null,
      toggleMenuFlag: false,
      editor: null,
      replacementText: "",
      isDragging: false,
      initialX: 0,
      initialY: 0,
      offsetX: 0,
      offsetY: 0,
      tocItems: [],
      styleMap: {},
      html: "",
      fontsize: "16",
    };
  },

  mounted() {
    this.initializeEditor();
    // // 测试直接插入图片
    // this.editor.commands.setContent(
    // );
    this.showMenu();
    // this.initScrollListeners();
  },
  computed: {
    canDeleteRow() {
      return this.isInTable && this.editor.can().deleteRow();
    },

    canDeleteColumn() {
      return this.isInTable && this.editor.can().deleteColumn();
    },

    isInTable() {
      return this.editor?.isActive("table");
    },
  },
  beforeDestroy() {
    this.editor.destroy();
  },

  methods: {
    // startAI
    startAI() {
      console.log("开始AI智能逻辑===");
    },
    // 绑定点击事件，出菜单
    showMenu() {
      // 获取编辑器根元素
      const editorElement = this.editor.view.dom;
      const menu = document.querySelector(".menu-wrap");
      const parent = document.querySelector(".editorElement");
      let downx;
      let downy;
      editorElement.addEventListener("mousedown", (e) => {
        console.log("鼠标位置====");
        const { clientX, clientY } = e;
        const rect = parent.getBoundingClientRect();
        // 步骤3: 计算基础相对坐标
        downx = clientX - rect.left;
        downy = clientY - rect.top;

        // 步骤4: 处理父元素自身滚动偏移
        downx += parent.scrollLeft;
        downy += parent.scrollTop;
        // 处理所有祖先元素的滚动偏移
        let current = parent.parentElement;
        while (current && current !== document.documentElement) {
          downx += current.scrollLeft;
          downy += current.scrollTop;
          current = current.parentElement;
        }
        // 步骤5: 修正边框影响
        const style = getComputedStyle(parent);
        const borderLeft = parseFloat(style.borderLeftWidth) || 0;
        const borderTop = parseFloat(style.borderTopWidth) || 0;
        downx -= borderLeft;
        downy -= borderTop;

        // 步骤6: 返回结果
        console.log("11111", "down-x:" + downx, ",down-y:" + downy);
      });

      // 添加鼠标抬起监听
      editorElement.addEventListener("mouseup", (event) => {
        const { from, to, empty } = this.editor.state.selection;
        if (!empty && from !== to) {
          // const menu = document.querySelector(".menu-wrap");
          // this.toggleMenuFlag = false;
          // const selectedText = this.editor.state.doc.textBetween(from, to);
          // console.log("选中文本:", selectedText);
          // console.log("鼠标位置:", { x: event.clientX, y: event.clientY });
          // this.scrollTop = event.clientY;
          // // 获取选区坐标
          // const startPos = this.editor.view.coordsAtPos(from);
          // const endPos = this.editor.view.coordsAtPos(to);
          // // 计算菜单位置
          // // menu.style.top = `${(startPos.top + endPos.top) / 2 - 35}px`;
          // menu.style.top = `${startPos.top  - 35}px`;
          // menu.style.left = `${startPos.left}px`;
          // this.toggleMenuFlag = true;

          // ------------    -------------

          const { clientX, clientY } = event;
          const rect = parent.getBoundingClientRect();
          // 步骤3: 计算基础相对坐标
          let x = clientX - rect.left;
          let y = clientY - rect.top;

          // 步骤4: 处理父元素自身滚动偏移
          x += parent.scrollLeft;
          y += parent.scrollTop;
          // 处理所有祖先元素的滚动偏移
          let current = parent.parentElement;
          while (current && current !== document.documentElement) {
            x += current.scrollLeft;
            y += current.scrollTop;
            current = current.parentElement;
          }
          // 步骤5: 修正边框影响
          const style = getComputedStyle(parent);
          const borderLeft = parseFloat(style.borderLeftWidth) || 0;
          const borderTop = parseFloat(style.borderTopWidth) || 0;
          x -= borderLeft;
          y -= borderTop;

          // 步骤6: 返回结果
          console.log("11111", "x:" + x, ",y:" + y);
          let realX = x < downx ? x : downx;
          let realy = y < downy ? y : downy;
          menu.style.top = `${realy - 55}px`;
          menu.style.left = `${realX}px`;
          this.toggleMenuFlag = true;
        } else {
          this.toggleMenuFlag = false;
          console.warn("请选中文本---");
        }
      });
    },

    initializeEditor() {
      // 创建 Yjs 文档
      // const ydoc = new Y.Doc();
      // // 创建 WebSocket 提供者
      // this.provider = new WebsocketProvider(
      //   "ws://localhost:1234",
      //   "room-name",
      //   ydoc
      // );

      const CustomDiv = Node.create({
        name: "customDiv",
        group: "block",
        content: "inline*", // 允许内联内容
        parseHTML() {
          return [{ tag: "div" }];
        },
        renderHTML({ HTMLAttributes }) {
          return ["div", HTMLAttributes, 0];
        },
        addAttributes() {
          return {
            "data-id": {
              default: null, // 默认值
              parseHTML: (element) => element.getAttribute("data-id"), // 从 HTML 解析
              renderHTML: (attributes) => ({
                "data-id": attributes["data-id"],
              }), // 渲染到 HTML
            },
            class: {
              default: "custom-div",
              renderHTML: (attributes) => {
                return {
                  class: `${attributes.class}`,
                };
              },
            },
          };
        },
      });
      this.editor = new Editor({
        element: this.$refs.editorElement,
        extensions: [
          CustomDiv,
          StarterKit.configure({
            // paragraph: {
            //   HTMLAttributes: {
            //     class: true,
            //   },
            // },
          }),
          textAlign,
          // 关键修复 1：正确配置 Image 扩展
          CustomImage,
          AlignableTable,
          // CustomTable,
          textStyle,
          TableRow,
          tableCell,
          TableHeader,
          TableCellMerge,
          HeadingWithId,
          CustomParagraph,
          markDown,
          Underline,
          FontSize,
          Color, // 启用颜色
          Highlight.configure({
            // 启用高亮
            multicolor: true, // 允许多种高亮颜色
          }),
          // yjs协同
          // Collaboration.configure({
          //   document: ydoc, // 绑定 Yjs 文档
          // }),
          // CollaborationCursor.configure({
          //   provider: this.provider, // 绑定 Yjs 提供者
          //   user: {
          //     name: "用户 " + Math.floor(Math.random() * 100), // 随机用户名
          //     color: "#" + Math.floor(Math.random() * 16777215).toString(16), // 随机颜色
          //   },
          // }),
        ],
        content:
          "<div class='note'>上传 Word 文档开始编辑...</div><div class='note'>开始测试的位置</div>",
        // 关键配置：启用 HTML 解析
        parseOptions: {
          preserveWhitespace: "full",
        },
      });
      this.editor.on("paste", ({ event }) => {
        this.handlePaste(event);
      });
      this.editor.on("update", () => {
        console.log("update======>");
        // this.updateToc();
        // this.$nextTick(() => this.updateToc());
      });
      // 确保在编辑器内容更新后绑定事件
      this.editor.on("transaction", () => {
        // this.updateToc();
      });
    },
    async handleFileUpload(event) {
      const file = event.target.files[0];
      if (!file) return;
      const zip = new JSZip();
      const zipContent = await zip.loadAsync(file);
      // 读取 Word 主文档内容
      const documentXml = await zipContent
        .file("word/document.xml")
        .async("text");
      // console.log("documentXmldocumentXml", documentXml);

      const docParser = new DOMParser();
      const xmlDoc = docParser.parseFromString(documentXml, "text/xml");
      // console.log("xmlDoc---", xmlDoc);
      console.log("xmlDoc---", Array.from(xmlDoc.getElementsByTagName("w:p")));

      const headings = Array.from(xmlDoc.getElementsByTagName("w:p")).filter(
        (p) => {
          const styleNode = p.getElementsByTagName("w\\:pPr > w\\:pStyle"); // 注意命名空间转义
          console.log("styleNode---", styleNode);
          return styleNode?.getAttribute("w:val")?.startsWith("Heading");
        }
      );

      const headding = headings.map((p) => {
        const level = parseInt(
          p
            .querySelector("w\\:pPr > w\\:pStyle")
            .getAttribute("w:val")
            .replace("Heading", "")
        );
        const text = p.querySelector("w\\:r > w\\:t")?.textContent || "";
        return { level, text };
      });
      console.log("headding===", headding);

      // 解析内容并转换为 Tiptap 格式
      const content = await this.parseWordDocument(xmlDoc, zipContent);
      this.content = content;

      this.editor.commands.setContent(content);
    },
    parseWordDocument(xmlDoc, zipContent) {
      console.log("zipContent---", zipContent);
      console.log("xmlDoc---", xmlDoc);
      const body = xmlDoc.getElementsByTagName("w:body")[0];
      console.log("body---", body);

      const paragraphs = Array.from(body.getElementsByTagName("w:p"));
      console.log("paragraphs---", paragraphs);
      let htmlContent = "";

      paragraphs.forEach((p) => {
        const elements = Array.from(p.childNodes);
        let paragraphHtml = "";

        elements.forEach((element) => {
          if (element.tagName === "w:r") {
            // 解析文本样式
            const textNode = element.getElementsByTagName("w:t")[0];
            const text = textNode?.textContent || "";
            const styles = this.parseRunStyles(element); // 核心：提取样式

            // 生成带样式的 HTML
            let styledText = text;
            if (styles) {
              styledText = `<span style="${styles}">${styledText}</span>`;
            }

            // 处理加粗、斜体（兼容原有逻辑）
            const isBold = element.getElementsByTagName("w:b").length > 0;
            const isItalic = element.getElementsByTagName("w:i").length > 0;
            if (isBold) styledText = `<strong>${styledText}</strong>`;
            if (isItalic) styledText = `<em>${styledText}</em>`;

            paragraphHtml += styledText;
          } else if (element.tagName === "w:drawing") {
            // 解析图片
            const imageId = element
              .getElementsByTagName("a:blip")[0]
              ?.getAttribute("r:embed");
            if (imageId) {
              const imagePath = `word/media/${this.getImageFileName(
                zipContent,
                imageId
              )}`;
              const imageFile = zipContent.file(imagePath);
              if (imageFile) {
                imageFile.async("base64").then((base64) => {
                  this.editor.commands.setImage({
                    src: `data:image/png;base64,${base64}`,
                  });
                });
              }
            }
          } else if (element.tagName === "w:numPr") {
            const listType =
              element.getElementsByTagName("w:ilvl")[0]?.textContent;
            const listHtml = listType
              ? `<li>${paragraphHtml}</li>`
              : paragraphHtml;
            htmlContent += `<ul>${listHtml}</ul>`;
          } else if (element.tagName === "w:tbl") {
            const rows = element.getElementsByTagName("w:tr");
            let tableHtml = "<table>";
            Array.from(rows).forEach((row) => {
              tableHtml += "<tr>";
              Array.from(row.getElementsByTagName("w:tc")).forEach((cell) => {
                tableHtml += `<td>${this.parseWordDocument(cell)}</td>`;
              });
              tableHtml += "</tr>";
            });
            htmlContent += `${tableHtml}</table>`;
          } else if (element.tagName === "w:pPr") {
          }
        });

        // 处理段落样式（如对齐方式）
        const paraStyles = this.parseParagraphStyles(p);
        if (paraStyles) {
          paragraphHtml = `<div style="${paraStyles}">${paragraphHtml}</div>`;
        }

        // 处理标题层级（原有逻辑）
        const headingLevel = this.getHeadingLevel(p);
        if (headingLevel) {
          htmlContent += `<h${headingLevel}>${paragraphHtml}</h${headingLevel}>`;
        } else {
          htmlContent += `<p>${paragraphHtml}</p>`;
        }
      });
      console.log("htmlContent===", htmlContent);
      return htmlContent;
    },

    // 解析单个 <w:r> 元素的样式（如颜色、字体）
    parseRunStyles(runElement) {
      const rPr = runElement.getElementsByTagName("w:rPr")[0];
      if (!rPr) return "";

      const styles = [];
      // 文字颜色
      const colorNode = rPr.getElementsByTagName("w:color")[0];
      if (colorNode) {
        const colorVal = colorNode.getAttribute("w:val");
        styles.push(`color: #${this.wordColorToHex(colorVal)}`);
      }

      // 背景色（高亮）
      const highlightNode = rPr.getElementsByTagName("w:highlight")[0];
      if (highlightNode) {
        const highlightVal = highlightNode.getAttribute("w:val");
        styles.push(`background-color: #${this.wordColorToHex(highlightVal)}`);
      }

      // 字体大小（单位：磅 -> px）
      const fontSizeNode = rPr.getElementsByTagName("w:sz")[0];
      if (fontSizeNode) {
        const pt = parseInt(fontSizeNode.getAttribute("w:val")) / 2; // 1pt = 1/72英寸 ≈ 1.333px
        styles.push(`font-size: ${Math.round(pt * 1.333)}px`); // 或转换为 px: Math.round(pt * 1.333) + 'px'
      }

      // 字体类型
      const fontNode = rPr.getElementsByTagName("w:rFonts")[0];
      if (fontNode) {
        const fontName = fontNode.getAttribute("w:ascii");
        styles.push(`font-family: ${fontName}`);
      }

      return styles.join("; ");
    },

    // 解析段落样式（如对齐）
    parseParagraphStyles(paragraph) {
      const pPr = paragraph.getElementsByTagName("w:pPr")[0];
      if (!pPr) return "";

      const styles = [];
      // 对齐方式
      const alignNode = pPr.getElementsByTagName("w:jc")[0];
      if (alignNode) {
        const alignVal = alignNode.getAttribute("w:val");
        styles.push(`text-align: ${alignVal}`);
      }

      return styles.join("; ");
    },

    // 将 Word 颜色值转换为 HEX（如 'FF0000' -> 'FF0000'）
    wordColorToHex(wordColor) {
      // Word 颜色值可能为自动（auto）或预设名称（如 'red'），需特殊处理
      if (!wordColor || wordColor === "auto") return "000000"; // 默认黑色
      return wordColor.startsWith("FF") ? wordColor.slice(2) : wordColor;
    },

    // 获取标题层级（示例：根据样式名判断）
    getHeadingLevel(paragraph) {
      const styleNode = paragraph.getElementsByTagName("w:pStyle")[0];
      const styleId = styleNode?.getAttribute("w:val") || "";
      return styleId.startsWith("Heading")
        ? styleId.replace("Heading", "")
        : null;
    },
    // 读取文件为ArrayBuffer
    readFile(file) {
      return new Promise((resolve) => {
        const reader = new FileReader();
        reader.onload = () => resolve(reader.result);
        reader.readAsArrayBuffer(file);
      });
    },
    transformParagraph(element) {
      console.log(element, "elementelement");
      if (element.type === "paragraph") {
        // let fontSize = element?.children?.[0]?.fontSize || "";
        // let styleName = "";
        // if (fontSize == "42" && !element.styleName) {
        // styleName = "Heading 1";
        // }
        if (element.alignment === "center") {
          element.styleName = "center";
        }
        // if (element.styleName == "heading 1") {
        // }
        return {
          ...element,
        };
      }
      return element;
    },
    // 绑定图片
    bindDragHandlers() {
      document.querySelectorAll(".resizable-image").forEach((img) => {
        if (img._bound) return;
        img._bound = true;

        this.$directives.draggableImage.bind(img, {
          value: {
            updateAttributes: (attrs) => {
              this.editor.commands.updateAttributes("image", attrs);
            },
          },
        });
      });
    },
    // ✅ 处理粘贴事件
    async handlePaste(event) {
      const items = event.clipboardData.items;
      for (const item of items) {
        if (item.type.startsWith("image")) {
          event.preventDefault();
          const blob = item.getAsFile();
          const base64 = await this.blobToBase64(blob);
          this.insertImage(base64);
          return;
        }
      }
    },
    // ✅ Blob 转 Base64
    blobToBase64(blob) {
      return new Promise((resolve) => {
        const reader = new FileReader();
        reader.onload = () => resolve(reader.result);
        reader.readAsDataURL(blob);
      });
    },

    // ✅ 插入图片到编辑器
    insertImage(src) {
      this.editor
        .chain()
        .focus()
        .insertContent({
          type: "image",
          attrs: {
            src,
            width: "300px",
            height: "auto",
          },
        })
        .run();
    },
    // 插入文字
    insertWord() {
      this.editor.chain().focus().insertContent("插入一段话············").run();
    },
    // 撤回上次操作
    undo() {
      this.editor.chain().focus().undo().run();
    },
    // 选中文字并替换
    checkWordAndChange() {
      if (!this.replacementText) return;
      if (!this.editor.state.selection.empty) {
        // this.editor
        //   .chain()
        //   .focus() // 保持焦点
        //   .deleteSelection() // 删除选中内容
        //   .insertContent(this.replacementText) // 插入新内容
        //   .run();
        const { state } = this.editor;
        const { from, to } = state.selection;

        if (from === to) return;

        const textNode = state.schema.text(
          this.replacementText,
          state.selection.$head.marks() // 获取光标位置格式
        );
        console.log("textNode==", textNode);

        const tr = state.tr.replaceWith(from, to, textNode);
        this.editor.view.dispatch(tr);
      } else {
        alert("请先选中要替换的文本");
      }
    },
    // 模拟右侧抽屉段落替换
    findWordAndChange() {
      if (!this.replacementText) return;
      const { state } = this.editor;
      const { doc } = state;
      let findText = this.replacementText;
      let replaceText = "替换后";
      let offset = 0;
      // 遍历文档中的所有节点，找到所有文本节点
      // 遍历文档中的所有节点
      doc.descendants((node, pos) => {
        if (node.isText) {
          const text = node.text;
          let index = text.indexOf(findText);
          while (index !== -1) {
            const from = pos + index + offset;
            const to = from + findText.length;
            // 执行替换操作
            this.editor
              .chain()
              .focus()
              .deleteRange({ from, to })
              .insertContentAt(from, replaceText)
              .run();

            // 更新偏移量，考虑替换文本的长度
            offset += replaceText.length - findText.length;
            // 继续查找下一个匹配项
            index = text.indexOf(findText, index + 1);
          }
        }
        return true;
      });
    },
    // 插入表格
    insertTable(rows, cols) {
      this.editor
        .chain()
        .focus()
        .insertTable({ rows, cols, withHeaderRow: false })
        .run();
    },
    // 获取选中表格
    getSelectedCells(selection) {
      if (selection instanceof CellSelection) {
        const cells = [];
        selection.forEach((node, pos) => {
          if (["table_cell", "table_header"].includes(node.type.name)) {
            cells.push({ node, pos: pos + 1 });
          }
        });
        return { cells };
      }
      return null;
    },
    // 新增列
    addColumn() {
      this.editor.chain().focus().addColumnAfter().run();
    },
    addRow() {
      this.editor.chain().focus().addRowAfter().run();
    },
    deleteTable() {
      this.editor.chain().focus().deleteTable().run();
    },
    mergeCells() {
      this.editor.chain().focus().mergeCells().run();
    },
    splitCell() {
      this.editor.chain().focus().splitCell().run();
    },
    deleteRow() {
      this.editor.chain().focus().deleteRow().run();
    },
    deleteColumn() {
      this.editor.chain().focus().deleteColumn().run();
    },
    turnBold() {
      this.editor.chain().focus().toggleBold().run();
    },
    toggleUnderline() {
      this.editor.chain().focus().toggleUnderline().run();
    },
    setFontSize() {
      console.log(this.fontsize, "this.fontsize");

      this.editor.chain().focus().setFontSize(this.fontsize).run();
    },
    handleDragStart(event) {
      this.isDragging = true;
      this.initialX = event.clientX;
      this.initialY = event.clientY;
      this.offsetX = event.target.offsetLeft;
      this.offsetY = event.target.offsetTop;
      event.dataTransfer.effectAllowed = "move";
      event.dataTransfer.setData("text/html", event.target.outerHTML);
    },

    handleDragOver(event) {
      if (this.isDragging && event.target.tagName === "TABLE") {
        event.preventDefault();
        const container = this.$refs.editorElement;
        const containerRect = container.getBoundingClientRect();
        const tableRect = event.target.getBoundingClientRect();

        const dx = event.clientX - this.initialX;
        const dy = event.clientY - this.initialY;

        let newX = this.offsetX + dx;
        let newY = this.offsetY + dy;

        // 边界检查
        if (newX < 0) {
          newX = 0;
        } else if (newX + tableRect.width > containerRect.width) {
          newX = containerRect.width - tableRect.width;
        }

        if (newY < 0) {
          newY = 0;
        } else if (newY + tableRect.height > containerRect.height) {
          newY = containerRect.height - tableRect.height;
        }

        event.target.style.left = newX + "px";
        event.target.style.top = newY + "px";
      }
    },

    handleDragEnd() {
      this.isDragging = false;
    },
    // 生成目录结构
    updateToc() {
      const headings = [];
      const transaction = this.editor.state.tr;

      // 遍历文档节点
      this.editor.state.doc.descendants((node, pos) => {
        if (node.type.name === "heading") {
          const id = this.generateID(node.textContent);

          // 添加锚点ID
          if (!node.attrs.id) {
            transaction.setNodeMarkup(pos, undefined, {
              ...node.attrs,
              id,
            });
          }

          headings.push({
            level: node.attrs.level,
            text: node.textContent,
            id: node.attrs.id || id,
          });
        }
      });

      // 提交事务更新节点属性
      transaction.setMeta("preventUpdate", true);
      this.editor.view.dispatch(transaction);

      this.tocItems = headings;
    },
    // 生成唯一ID
    generateID(text) {
      return text
        .toLowerCase()
        .replace(/[^a-z0-9]+/g, "-")
        .replace(/(^-|-$)/g, "");
    },
    // 滚动到对应标题
    scrollToHeading(id) {
      const element = document.getElementById(id);
      if (element) {
        element.scrollIntoView({
          behavior: "smooth",
          block: "start",
        });
      }
    },
    // 导入Markdown数据
    insertMarkDown() {
      this.editor.commands.setContent(markdownData);
    },
    // 导出markdown数据
    exportMarkDown() {
      const markdownOutput = this.editor.storage.markdown.getMarkdown();
      console.log(markdownOutput);
    },
    async setAlignment(align) {
      // 统一处理所有元素对齐

      if (this.editor.isActive("image")) {
        this.editor.chain().focus().updateAttributes("image", { align }).run();
      } else if (this.editor.isActive("table")) {
        // let table = await this.getCurrentTable();
        console.log(this.editor.chain().focus(), "ttt");
        // table.parentNode.style.justifyContent = "center";
        this.editor.chain().focus().setTextAlign(align).run();
      } else {
        this.editor.chain().focus().setTextAlign(align).run();
      }
    },
    // 获取当前聚焦的完整表格
    getCurrentTable() {
      // 获取当前选区节点
      const { $from } = this.editor.state.selection;
      const currentNode = this.editor.view.nodeDOM($from.pos);

      // 向上遍历查找 table 元素
      if (currentNode) {
        const tableElement = currentNode.closest("table");
        return tableElement;
      }
      return null;
    },
  },
};
</script>

<style scoped>
/* 组件样式 */
</style>

<style lang="scss">
.menu-wrap {
  position: absolute;
  display: flex;
  white-space: nowrap;
  background: #dfe7bf;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
  padding: 4px;
  border-radius: 4px;
  transform: translateZ(0);
  transition: transform 0.2s ease, opacity 0.2s ease;
  z-index: 1;
  opacity: 0.9;
  // display: none; /* 默认隐藏 */
}
.mainContent {
  display: flex;
  height: 545px;
  .toc-sidebar {
    width: 20%;
    overflow-y: scroll;
    .toc-item {
      white-space: nowrap;
      text-align: left;
      text-overflow: ellipsis;
      overflow: hidden;
      cursor: pointer;
      margin: 4px 0;
    }
  }
  .editorElement {
    flex: 1;
    overflow-y: scroll;
    position: relative;
  }
}
/* 全局文档样式 */
.doc-paragraph {
  margin: 12px 0;
  line-height: 1.6;
  font-family: "SimSun", serif;
}

/* 表格样式 */
table {
  border-collapse: collapse;
  margin: 1rem 0;
  table-layout: fixed;
  max-width: 100% !important;
}

td,
th {
  padding: 8px;
  min-width: 50px;
  position: relative;
  vertical-align: top;
}

th {
  font-weight: bold;
}

/* 合并单元格提示 */
[colspan]:not([colspan="1"]),
[rowspan]:not([rowspan="1"]) {
  background-color: #f0f8ff;
}

/* 列宽调整手柄 */
.column-resize-handle {
  position: absolute;
  right: 0;
  top: 0;
  bottom: 0;
  width: 4px;
  background-color: #adf;
  pointer-events: none;
  cursor: pointer;
}

img {
  max-width: 100%;
  height: auto;
  border: 1px solid red !important; /* 调试用边框 */
}
/* 全局样式或组件内样式 */
.editor-image {
  border: 1px solid #ddd !important; /* 调试用边框 */
}

/* 覆盖潜在冲突样式 */
.ProseMirror {
  width: 100%;
  padding: 20px 12px;
  box-sizing: border-box;
  img {
    max-wdith: 100% !important;
  }
  .tableWrapper {
    display: flex;
    align-items: center;
  }
  table {
    border-collapse: collapse;
    border: 1px solid #000;
    margin: 5px;
  }
  td,
  td {
    border: 1px solid #9e9797; /* 边框颜色和粗细 */
    padding: 8px; /* 内边距 */
  }
  h1,
  h2,
  h3,
  h4,
  h5 {
    font-size: 16px;
    text-align: left;
    margin: 12px 0;
  }
  h1 {
    text-indent: 15px;
  }
  h2 {
    text-indent: 25px;
  }
  h3,
  h4,
  h5 {
    text-indent: 15px;
  }
  p,
  div {
    text-align: left;
    text-indent: 20px;
  }
  p {
    margin: 12px 0;
  }
  div {
    line-height: 20px;
  }
  ul {
    list-style-type: lower-alpha;
  }
  .toc1 {
    text-indent: 10px;
  }
  .toc2 {
    text-indent: 20px;
  }
  .toc3 {
    text-indent: 30px;
  }
  .toc4 {
    text-indent: 40px;
  }
  .text-center {
    text-align: center;
    font-size: 20px;
    font-weight: 700;
    margin: 20px 0;
  }
  .ul-list {
    text-indent: 50px;
    line-height: 22px;
  }
  .note {
    text-align: center;
  }
}
/* ✅ 确保图片可见性 */
.resizable-image {
  display: block !important;
  max-width: 100%;
  height: auto;
  margin: 10px auto;
  position: relative !important;
}

.resizable-image::after {
  content: "";
  position: absolute;
  bottom: -8px;
  right: -8px;
  width: 16px;
  height: 16px;
  background: #2196f3;
  border-radius: 50%;
  cursor: nwse-resize;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
}
button {
  margin: 5px;
}

/* 统一对齐样式 */
.ProseMirror {
  p[data-text-align],
  h1[data-text-align],
  h2[data-text-align] {
    &[data-text-align="left"] {
      text-align: left;
    }
    &[data-text-align="center"] {
      text-align: center;
    }
    &[data-text-align="right"] {
      text-align: right;
    }
  }

  /* 图片浮动处理 */
  .float-image {
    max-width: 60%;
    &[data-align="left"] {
      float: left;
      margin: 0 1rem 1rem 0;
    }
    &[data-align="right"] {
      float: right;
      margin: 0 0 1rem 1rem;
    }
    &[data-align="center"] {
      display: block;
      margin: 1rem auto;
    }
  }
}

/* 清除浮动 */
.ProseMirror::after {
  content: "";
  display: table;
  clear: both;
}
</style>
